

package com.code.ape.codeape.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.code.ape.codeape.admin.api.entity.SysDept;
import com.code.ape.codeape.admin.api.entity.SysDeptRelation;
import com.code.ape.codeape.admin.mapper.SysDeptMapper;
import com.code.ape.codeape.admin.service.SysDeptRelationService;
import com.code.ape.codeape.admin.service.SysDeptService;
import com.code.ape.codeape.common.core.constant.CommonConstants;
import com.code.ape.codeape.common.core.constant.SecurityConstants;
import com.code.ape.codeape.common.core.entity.BaseParam;
import com.code.ape.codeape.common.security.service.CodeapeUser;
import com.code.ape.codeape.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门管理 服务实现类
 * </p>
 *
 * @author 公众号：码猿技术专栏   版权：不才陈某所署，侵权必究
 * @since 2019/2/1
 */
@Service
@RequiredArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

	private final SysDeptRelationService sysDeptRelationService;

	/**
	 * 添加信息部门
	 * @param dept 部门
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveDept(SysDept dept) {
		dept.setHosId(Objects.requireNonNull(SecurityUtils.getUser()).getHosId());
		this.save(dept);
		sysDeptRelationService.saveDeptRelation(dept);
		return Boolean.TRUE;
	}

	/**
	 * 删除部门
	 * @param id 部门 ID
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean removeDeptById(Long id) {
		//step1 删除该科室
		int rows1 = baseMapper.deleteById(id);
		AssertUtil.isTrue(rows1==1,"删除失败！");
		// 删除关联关系
		sysDeptRelationService.remove(Wrappers.<SysDeptRelation>lambdaQuery()
				.eq(SysDeptRelation::getAncestor,id)
				.or()
				.eq(SysDeptRelation::getDescendant,id)
		);
		return Boolean.TRUE;
	}

	/**
	 * 更新部门
	 * @param sysDept 部门信息
	 * @return 成功、失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateDeptById(SysDept sysDept) {
		//step1 查询
		SysDept dept = baseMapper.selectById(sysDept.getDeptId());
		AssertUtil.isTrue(Objects.nonNull(dept),"科室不存在！");

		//step2 更新
		int rows = baseMapper.updateById(sysDept);
		AssertUtil.isTrue(rows==1,"修改失败！");

		//step3 比较祖先节点是否改变，改变则更新科室关联表
		if (!Objects.equals(sysDept.getParentId(),dept.getParentId())){
			//删除关系
			sysDeptRelationService.remove(Wrappers.<SysDeptRelation>lambdaQuery()
					.eq(SysDeptRelation::getAncestor, dept.getParentId())
					.eq(SysDeptRelation::getDescendant, dept.getDeptId())
			);

			sysDeptRelationService.saveDeptRelation(sysDept);
		}
		return Boolean.TRUE;
	}

	@Override
	public List<Long> listChildDeptId(Long deptId) {
		List<SysDeptRelation> deptRelations = sysDeptRelationService.list(Wrappers.<SysDeptRelation>lambdaQuery()
			.eq(SysDeptRelation::getAncestor, deptId)
			.ne(SysDeptRelation::getDescendant, deptId));
		if (CollUtil.isNotEmpty(deptRelations)) {
			return deptRelations.stream().map(SysDeptRelation::getDescendant).collect(Collectors.toList());
		}
		return new ArrayList<>();
	}

	/**
	 * 查询全部部门树
	 * @return 树
	 */
	@Override
	public List<Tree<Long>> listDeptTrees() {
		//查询当前医院所属的全部部门树
		return getDeptTree(this.lambdaQuery()
				.eq(SysDept::getHosId, Objects.requireNonNull(SecurityUtils.getUser()).getHosId())
				.list(), 0L);
	}

	/**
	 * 查询用户部门树
	 * @return
	 */
	@Override
	public List<Tree<Long>> listCurrentUserDeptTrees() {
		Long deptId = SecurityUtils.getUser().getDeptId();
		List<Long> descendantIdList = sysDeptRelationService
			.list(Wrappers.<SysDeptRelation>query().lambda().eq(SysDeptRelation::getAncestor, deptId))
			.stream()
			.map(SysDeptRelation::getDescendant)
			.collect(Collectors.toList());

		List<SysDept> deptList = baseMapper.selectBatchIds(descendantIdList);
		Optional<SysDept> dept = deptList.stream().filter(item -> item.getDeptId().intValue() == deptId).findFirst();
		return getDeptTree(deptList, dept.isPresent() ? dept.get().getParentId() : 0L);
	}

	@Override
	public List<SysDept> listDept(BaseParam param) {
		//根据当前登录用户的权限筛选
		CodeapeUser codeapeUser = Objects.requireNonNull(SecurityUtils.getUser());
		return baseMapper.selectList(Wrappers.<SysDept>lambdaQuery()
				.eq(SysDept::getHosId,codeapeUser.getHosId())
				.in(CollectionUtil.isNotEmpty(param.getDataAuth()), SysDept::getDeptId,Arrays.asList(codeapeUser.getDeptAuths())));
	}

	/**
	 * 构建部门树
	 * @param depts 部门
	 * @param parentId 父级id
	 * @return
	 */
	private List<Tree<Long>> getDeptTree(List<SysDept> depts, Long parentId) {
		List<TreeNode<Long>> collect = depts.stream()
			.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
			.sorted(Comparator.comparingInt(SysDept::getSortOrder))
			.map(dept -> {
				TreeNode<Long> treeNode = new TreeNode();
				treeNode.setId(dept.getDeptId());
				treeNode.setParentId(dept.getParentId());
				treeNode.setName(dept.getName());
				treeNode.setWeight(dept.getSortOrder());
				// 扩展属性
				Map<String, Object> extra = new HashMap<>(2);
				extra.put("createTime", dept.getCreateTime());
				treeNode.setExtra(extra);
				return treeNode;
			})
			.collect(Collectors.toList());

		return TreeUtil.build(collect, parentId);
	}

}
